<template>
  <div class="common-table bg-white dark:bg-dark rounded-lg shadow-sm">
    <!-- 搜索筛选区域 -->
    <div
      v-if="showSearch"
      class="search-form p-4 border-b border-gray-200 dark:border-gray-700"
    >
      <el-form
        ref="searchFormRef"
        :model="searchForm"
        :inline="true"
        class="search-form-content"
      >
        <template v-for="field in searchFields" :key="field.prop">
          <el-form-item :label="field.label" :prop="field.prop">
            <!-- 输入框 -->
            <el-input
              v-if="field.type === 'input'"
              v-model="searchForm[field.prop]"
              :placeholder="field.placeholder || `请输入${field.label}`"
              clearable
              class="!w-48"
            />
            <!-- 选择器 -->
            <el-select
              v-else-if="field.type === 'select'"
              v-model="searchForm[field.prop]"
              :placeholder="field.placeholder || `请选择${field.label}`"
              clearable
              class="!w-48"
            >
              <el-option
                v-for="option in field.options"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
            <!-- 日期选择器 -->
            <el-date-picker
              v-else-if="field.type === 'date'"
              v-model="searchForm[field.prop]"
              type="date"
              :placeholder="field.placeholder || `请选择${field.label}`"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              class="!w-48"
            />
            <!-- 日期范围选择器 -->
            <el-date-picker
              v-else-if="field.type === 'daterange'"
              v-model="searchForm[field.prop]"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              class="!w-80"
            />
          </el-form-item>
        </template>

        <el-form-item class="search-buttons">
          <el-button type="primary" @click="handleSearch">
            <IconifyIconOffline :icon="SearchIcon" class="mr-1" />
            搜索
          </el-button>
          <el-button @click="handleReset">
            <IconifyIconOffline :icon="RefreshIcon" class="mr-1" />
            重置
          </el-button>
          <!--          <el-button-->
          <!--            v-if="searchFields.length > 4"-->
          <!--            link-->
          <!--            type="primary"-->
          <!--            @click="toggleSearchExpand"-->
          <!--          >-->
          <!--            {{ searchExpanded ? "收起" : "展开" }}-->
          <!--            <IconifyIconOffline-->
          <!--              :icon="searchExpanded ? ArrowUpIcon : ArrowDownIcon"-->
          <!--              class="ml-1"-->
          <!--            />-->
          <!--          </el-button>-->
          <!-- 自定义搜索按钮插槽 -->
          <slot name="search-buttons" />
        </el-form-item>
      </el-form>
    </div>

    <!-- 表格工具栏 -->
    <div class="table-toolbar p-4 flex justify-between items-center">
      <div class="toolbar-left flex items-center space-x-3">
        <h3
          v-if="title"
          class="text-lg font-medium text-gray-800 dark:text-gray-200 m-0"
        >
          {{ title }}
        </h3>
        <slot name="toolbar-left" />
      </div>

      <div class="toolbar-right flex items-center space-x-2">
        <slot name="toolbar-add" />
        <slot name="toolbar-right" />
        <!-- 刷新按钮 -->
        <el-button
          v-if="showRefresh"
          size="small"
          :loading="loading"
          @click="handleRefresh"
        >
          <IconifyIconOffline :icon="RefreshIcon" />
        </el-button>
        <!-- 列设置 -->
        <el-popover
          v-if="showColumnSetting"
          placement="bottom-end"
          :width="200"
          trigger="click"
        >
          <template #reference>
            <el-button size="small">
              <IconifyIconOffline :icon="SettingIcon" />
            </el-button>
          </template>
          <div class="column-setting">
            <div
              class="p-2 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"
            >
              <span class="font-medium">列设置</span>
              <el-button link size="small" @click="resetColumns"
                >重置
              </el-button>
            </div>
            <div class="p-2 max-h-60 overflow-y-auto">
              <el-checkbox
                v-for="col in dynamicColumns"
                :key="col.prop"
                v-model="col.visible"
                :label="col.label"
                class="w-full mb-2"
                @change="updateTableColumns"
              />
            </div>
          </div>
        </el-popover>
      </div>
    </div>

    <!-- 表格主体 -->
    <div class="table-container w-full">
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="tableData"
        :height="height"
        :max-height="maxHeight"
        style="width: 100%"
        :stripe="stripe"
        :border="border"
        :fit="fit"
        :show-header="showHeader"
        :highlight-current-row="highlightCurrentRow"
        :row-class-name="rowClassName"
        :row-style="rowStyle"
        :cell-class-name="cellClassName"
        :cell-style="cellStyle"
        :header-row-class-name="headerRowClassName"
        :header-row-style="headerRowStyle"
        :header-cell-class-name="headerCellClassName"
        :header-cell-style="headerCellStyle"
        :row-key="rowKey"
        :empty-text="emptyText"
        :default-expand-all="defaultExpandAll"
        :expand-row-keys="expandRowKeys"
        :default-sort="defaultSort"
        :tooltip-effect="tooltipEffect"
        :show-summary="showSummary"
        :sum-text="sumText"
        :summary-method="summaryMethod"
        :span-method="spanMethod"
        :select-on-indeterminate="selectOnIndeterminate"
        :indent="indent"
        :lazy="lazy"
        :load="load"
        :tree-props="treeProps"
        @select="handleSelect"
        @select-all="handleSelectAll"
        @selection-change="handleSelectionChange"
        @cell-mouse-enter="handleCellMouseEnter"
        @cell-mouse-leave="handleCellMouseLeave"
        @cell-click="handleCellClick"
        @cell-dblclick="handleCellDblclick"
        @row-click="handleRowClick"
        @row-contextmenu="handleRowContextmenu"
        @row-dblclick="handleRowDblclick"
        @header-click="handleHeaderClick"
        @header-contextmenu="handleHeaderContextmenu"
        @sort-change="handleSortChange"
        @filter-change="handleFilterChange"
        @current-change="handleCurrentChange"
        @header-dragend="handleHeaderDragend"
        @expand-change="handleExpandChange"
      >
        <!-- 自定义列 -->
        <template v-for="column in visibleColumns" :key="column.prop">
          <!-- 选择列 -->
          <el-table-column
            v-if="column.type === 'selection'"
            type="selection"
            :width="column.width || 55"
            :fixed="column.fixed"
            :align="column.align || 'center'"
            :selectable="column.selectable"
          />
          <!-- 索引列 -->
          <el-table-column
            v-else-if="column.type === 'index'"
            type="index"
            :label="column.label || '序号'"
            :width="column.width || 60"
            :fixed="column.fixed"
            :align="column.align || 'center'"
            :index="column.index"
          />
          <!-- 展开列 -->
          <el-table-column
            v-else-if="column.type === 'expand'"
            type="expand"
            :fixed="column.fixed"
            :width="column.width || 55"
            :align="column.align || 'center'"
          >
            <template #default="{ row, $index }">
              <slot name="expand" :row="row" :index="$index" />
            </template>
          </el-table-column>
          <!-- 普通列 -->
          <el-table-column
            v-else
            :prop="column.prop"
            :label="column.label"
            :width="column.width"
            :min-width="column.minWidth"
            :fixed="column.fixed"
            :render-header="column.renderHeader"
            :sortable="column.sortable"
            :sort-method="column.sortMethod"
            :sort-by="column.sortBy"
            :sort-orders="column.sortOrders"
            :resizable="column.resizable"
            :formatter="column.formatter"
            :show-overflow-tooltip="column.showOverflowTooltip"
            :align="column.align"
            :header-align="column.headerAlign"
            :class-name="column.className"
            :label-class-name="column.labelClassName"
            :filters="column.filters"
            :filter-placement="column.filterPlacement"
            :filter-multiple="column.filterMultiple"
            :filter-method="column.filterMethod"
            :filtered-value="column.filteredValue"
          >
            <template
              v-if="column.slot"
              #default="{ row, column: col, $index }"
            >
              <slot
                :name="column.slot"
                :row="row"
                :column="col"
                :index="$index"
              />
            </template>
            <template
              v-if="column.headerSlot"
              #header="{ column: col, $index }"
            >
              <slot :name="column.headerSlot" :column="col" :index="$index" />
            </template>
          </el-table-column>
        </template>
      </el-table>
    </div>

    <!-- 分页 -->
    <div
      v-if="showPagination"
      class="pagination-container p-4 flex justify-end"
    >
      <el-pagination
        v-model:current-page="paginationConfig.current"
        v-model:page-size="paginationConfig.size"
        :page-sizes="paginationConfig.pageSizes"
        :size="paginationConfig.paginationSize"
        :disabled="paginationConfig.disabled"
        :background="paginationConfig.background"
        :layout="paginationConfig.layout"
        :total="paginationConfig.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentPageChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from "vue";
import { cloneDeep } from "@pureadmin/utils";
import { IconifyIconOffline } from "@/components/ReIcon";

// 导入需要的图标
import RefreshIcon from "~icons/ep/refresh";
import SearchIcon from "~icons/ep/search";
import SettingIcon from "~icons/ep/setting";
import ArrowUpIcon from "~icons/ep/arrow-up";
import ArrowDownIcon from "~icons/ep/arrow-down";

export interface SearchField {
  prop: string;
  label: string;
  type: "input" | "select" | "date" | "daterange";
  placeholder?: string;
  options?: Array<{ label: string; value: any }>;
}

export interface TableColumn {
  prop?: string;
  label: string;
  width?: string | number;
  minWidth?: string | number;
  fixed?: boolean | string;
  renderHeader?: Function;
  sortable?: boolean | string;
  sortMethod?: Function;
  sortBy?: string | Array<string> | Function;
  sortOrders?: Array<string>;
  resizable?: boolean;
  formatter?: Function;
  showOverflowTooltip?: boolean;
  align?: string;
  headerAlign?: string;
  className?: string;
  labelClassName?: string;
  filters?: Array<{ text: string; value: any }>;
  filterPlacement?: string;
  filterMultiple?: boolean;
  filterMethod?: Function;
  filteredValue?: Array<any>;
  type?: "selection" | "index" | "expand";
  index?: number | Function;
  selectable?: Function;
  slot?: string;
  headerSlot?: string;
  visible?: boolean;
}

export interface Pagination {
  current: number;
  size: number;
  total: number;
  pageSizes: number[];
  layout: string;
  background: boolean;
  disabled: boolean;
  paginationSize: string;
}

defineOptions({
  name: "ReCommonTable"
});

const props = withDefaults(
  defineProps<{
    // 基础配置
    title?: string;
    loading?: boolean;
    data?: any[];
    columns?: TableColumn[];
    height?: string | number;
    maxHeight?: string | number;
    stripe?: boolean;
    border?: boolean;
    fit?: boolean;
    showHeader?: boolean;
    highlightCurrentRow?: boolean;
    rowClassName?: string | Function;
    rowStyle?: object | Function;
    cellClassName?: string | Function;
    cellStyle?: object | Function;
    headerRowClassName?: string | Function;
    headerRowStyle?: object | Function;
    headerCellClassName?: string | Function;
    headerCellStyle?: object | Function;
    rowKey?: string | Function;
    emptyText?: string;
    defaultExpandAll?: boolean;
    expandRowKeys?: Array<any>;
    defaultSort?: object;
    tooltipEffect?: string;
    showSummary?: boolean;
    sumText?: string;
    summaryMethod?: Function;
    spanMethod?: Function;
    selectOnIndeterminate?: boolean;
    indent?: number;
    lazy?: boolean;
    load?: Function;
    treeProps?: object;

    // 搜索配置
    showSearch?: boolean;
    searchFields?: SearchField[];

    // 分页配置
    showPagination?: boolean;
    pagination?: Partial<Pagination>;

    // 工具栏配置
    showRefresh?: boolean;
    showColumnSetting?: boolean;
  }>(),
  {
    loading: false,
    data: () => [],
    columns: () => [],
    stripe: true,
    border: true,
    fit: true,
    showHeader: true,
    highlightCurrentRow: false,
    emptyText: "暂无数据",
    defaultExpandAll: false,
    tooltipEffect: "dark",
    showSummary: false,
    sumText: "合计",
    selectOnIndeterminate: true,
    indent: 16,
    lazy: false,

    showSearch: true,
    searchFields: () => [],

    showPagination: true,
    pagination: () => ({
      current: 1,
      size: 10,
      total: 0,
      pageSizes: [10, 20, 50, 100],
      layout: "total, sizes, prev, pager, next, jumper",
      background: true,
      disabled: false,
      paginationSize: "default"
    }),

    showRefresh: true,
    showColumnSetting: true
  }
);

const emit = defineEmits<{
  search: [searchForm: any];
  refresh: [];
  "size-change": [size: number];
  "current-change": [current: number];
  select: [selection: any[], row: any];
  "select-all": [selection: any[]];
  "selection-change": [selection: any[]];
  "cell-mouse-enter": [row: any, column: any, cell: any, event: Event];
  "cell-mouse-leave": [row: any, column: any, cell: any, event: Event];
  "cell-click": [row: any, column: any, cell: any, event: Event];
  "cell-dblclick": [row: any, column: any, cell: any, event: Event];
  "row-click": [row: any, column: any, event: Event];
  "row-contextmenu": [row: any, column: any, event: Event];
  "row-dblclick": [row: any, column: any, event: Event];
  "header-click": [column: any, event: Event];
  "header-contextmenu": [column: any, event: Event];
  "sort-change": [data: { column: any; prop: string; order: string }];
  "filter-change": [filters: any];
  "current-row-change": [currentRow: any, oldCurrentRow: any];
  "header-dragend": [
    newWidth: number,
    oldWidth: number,
    column: any,
    event: Event
  ];
  "expand-change": [row: any, expandedRows: any[]];
}>();

// 响应式数据
const tableRef = ref();
const searchFormRef = ref();
const searchForm = ref<Record<string, any>>({});
const searchExpanded = ref(false);
const dynamicColumns = ref<TableColumn[]>([]);

// 计算属性
const tableData = computed(() => props.data || []);

const paginationConfig = computed(() => ({
  current: 1,
  size: 10,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: "total, sizes, prev, pager, next, jumper",
  background: true,
  disabled: false,
  paginationSize: "default",
  ...props.pagination
}));

const visibleColumns = computed(() => {
  return dynamicColumns.value.filter(col => col.visible !== false);
});

// 初始化搜索表单
const initSearchForm = () => {
  const form: Record<string, any> = {};
  props.searchFields?.forEach(field => {
    form[field.prop] = field.type === "daterange" ? [] : "";
  });
  searchForm.value = form;
};

// 初始化列配置
const initColumns = () => {
  dynamicColumns.value = cloneDeep(props.columns).map(col => ({
    ...col,
    visible: col.visible !== false
  }));
};

// 搜索处理
const handleSearch = () => {
  emit("search", { ...searchForm.value });
};

// 重置搜索
const handleReset = () => {
  searchFormRef.value?.resetFields();
  initSearchForm();
  emit("search", { ...searchForm.value });
};

// 切换搜索展开状态
const toggleSearchExpand = () => {
  searchExpanded.value = !searchExpanded.value;
};

// 刷新
const handleRefresh = () => {
  emit("refresh");
};

// 重置列设置
const resetColumns = () => {
  dynamicColumns.value.forEach(col => {
    col.visible = true;
  });
  updateTableColumns();
};

// 更新表格列
const updateTableColumns = () => {
  // 触发表格重新渲染
};

// 分页事件
const handleSizeChange = (size: number) => {
  emit("size-change", size);
};

const handleCurrentPageChange = (current: number) => {
  emit("current-change", current);
};

// 表格事件处理
const handleSelect = (selection: any[], row: any) => {
  emit("select", selection, row);
};

const handleSelectAll = (selection: any[]) => {
  emit("select-all", selection);
};

const handleSelectionChange = (selection: any[]) => {
  emit("selection-change", selection);
};

const handleCellMouseEnter = (
  row: any,
  column: any,
  cell: any,
  event: Event
) => {
  emit("cell-mouse-enter", row, column, cell, event);
};

const handleCellMouseLeave = (
  row: any,
  column: any,
  cell: any,
  event: Event
) => {
  emit("cell-mouse-leave", row, column, cell, event);
};

const handleCellClick = (row: any, column: any, cell: any, event: Event) => {
  emit("cell-click", row, column, cell, event);
};

const handleCellDblclick = (row: any, column: any, cell: any, event: Event) => {
  emit("cell-dblclick", row, column, cell, event);
};

const handleRowClick = (row: any, column: any, event: Event) => {
  emit("row-click", row, column, event);
};

const handleRowContextmenu = (row: any, column: any, event: Event) => {
  emit("row-contextmenu", row, column, event);
};

const handleRowDblclick = (row: any, column: any, event: Event) => {
  emit("row-dblclick", row, column, event);
};

const handleHeaderClick = (column: any, event: Event) => {
  emit("header-click", column, event);
};

const handleHeaderContextmenu = (column: any, event: Event) => {
  emit("header-contextmenu", column, event);
};

const handleSortChange = (data: {
  column: any;
  prop: string;
  order: string;
}) => {
  emit("sort-change", data);
};

const handleFilterChange = (filters: any) => {
  emit("filter-change", filters);
};

const handleCurrentChange = (currentRow: any, oldCurrentRow: any) => {
  emit("current-row-change", currentRow, oldCurrentRow);
};

const handleHeaderDragend = (
  newWidth: number,
  oldWidth: number,
  column: any,
  event: Event
) => {
  emit("header-dragend", newWidth, oldWidth, column, event);
};

const handleExpandChange = (row: any, expandedRows: any[]) => {
  emit("expand-change", row, expandedRows);
};

// 生命周期
onMounted(() => {
  initSearchForm();
  initColumns();
});

// 监听props变化
watch(
  () => props.searchFields,
  () => {
    initSearchForm();
  },
  { deep: true }
);

watch(
  () => props.columns,
  () => {
    initColumns();
  },
  { deep: true }
);

// 暴露方法
defineExpose({
  tableRef,
  searchFormRef,
  searchForm,
  handleSearch,
  handleReset,
  handleRefresh
});
</script>

<style scoped>
.common-table {
  --el-table-border-color: #e5e7eb;

  width: 100%;
}

.dark .common-table {
  --el-table-border-color: #374151;
}

.table-container {
  width: 100%;
}

.search-form-content {
  display: flex;
  flex-wrap: wrap;
  gap: 0 33px;
}

.search-buttons {
  margin-left: auto !important;
}

.column-setting {
  max-height: 300px;
}

:deep(.el-table) {
  --el-table-header-bg-color: #f8fafc;
}

.dark :deep(.el-table) {
  --el-table-header-bg-color: #1f2937;
}

:deep(.el-pagination) {
  justify-content: flex-end;
}

:deep(.el-form--inline .el-form-item) {
  margin-right: 0 !important;
}
</style>
